home *** CD-ROM | disk | FTP | other *** search
- /* polygons.c */
-
- /*
- * Mesa 3-D graphics library
- * Version: 1.2
- * Copyright (C) 1995 Brian Paul (brianp@ssec.wisc.edu)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
- /*
- $Id: polygons.c,v 1.34 1995/11/30 00:21:55 brianp Exp $
-
- $Log: polygons.c,v $
- * Revision 1.34 1995/11/30 00:21:55 brianp
- * restored old gl_polygon_edge function
- *
- * Revision 1.33 1995/11/14 21:49:40 brianp
- * optimized polygon rendering setup
- *
- * Revision 1.32 1995/11/04 20:09:07 brianp
- * optimized gl_polygon_edge()
- *
- * Revision 1.31 1995/10/29 19:14:44 brianp
- * added glPolygonOffsetEXT display list support
- *
- * Revision 1.30 1995/10/27 20:30:29 brianp
- * added glPolygonOffsetEXT()
- *
- * Revision 1.29 1995/10/24 20:52:15 brianp
- * renamed COMPUTE_PLANE_Z as gl_compute_z
- * renamed polygon_edge as gl_polygon_edge
- * use new color interpolation based on fixed point arithmetic
- * removed dead code
- *
- * Revision 1.28 1995/10/22 21:20:50 brianp
- * changed 0.5 to 0.5F in COMPUTE_PLANE_Z calls
- *
- * Revision 1.27 1995/10/22 20:29:37 brianp
- * removed dead code
- *
- * Revision 1.26 1995/10/19 15:48:28 brianp
- * added gamma support
- * changed DD.color arguments to GLubytes
- *
- * Revision 1.25 1995/10/17 21:40:04 brianp
- * added fast_flat_rgba_z_polygon() function
- * removed fast_ci/rgb_polygon() functions
- *
- * Revision 1.24 1995/09/20 18:20:39 brianp
- * prototype device driver changes described
- *
- * Revision 1.23 1995/09/13 14:51:05 brianp
- * use CC.NewState convention
- * use DEFARRAY/UNDEFARRAY macros for Mac
- * replaced VB.Vs and VB.Vt with VB.TexCoord
- *
- * Revision 1.22 1995/07/28 21:34:16 brianp
- * support polygons draw in viewport larger than window
- *
- * Revision 1.21 1995/07/15 14:04:50 brianp
- * fixed texture coord interpolation bug
- *
- * Revision 1.20 1995/07/11 17:47:45 brianp
- * round window coords to nearest int, not truncate, in fast_ci|rgba_polygon
- *
- * Revision 1.19 1995/06/20 16:32:40 brianp
- * new depth buffer value computations
- * introduced new triangle rasterizer code, experimental, not used yet
- *
- * Revision 1.18 1995/06/12 15:43:35 brianp
- * changed color arrays to GLubyte
- * new interpolation functions
- *
- * Revision 1.17 1995/06/05 20:27:53 brianp
- * added CC.Polygon.Unfilled stuff
- *
- * Revision 1.16 1995/06/02 13:59:46 brianp
- * added fast_smooth_rgba_z_polygon() function
- *
- * Revision 1.15 1995/05/31 19:34:12 brianp
- * replaced MAX_VERTICES with VB_MAX
- *
- * Revision 1.14 1995/05/22 21:02:41 brianp
- * Release 1.2
- *
- * Revision 1.13 1995/05/12 17:01:05 brianp
- * changed CC.Mode!=0 to INSIDE_BEGIN_END
- *
- * Revision 1.12 1995/04/18 15:48:23 brianp
- * fixed assignment of NULL to function pointers to prevent warnings on Suns
- *
- * Revision 1.11 1995/04/12 15:36:15 brianp
- * updated to use DD.draw_* function pointers
- *
- * Revision 1.10 1995/03/27 20:31:53 brianp
- * new Texture.Enabled scheme
- *
- * Revision 1.9 1995/03/24 19:28:13 brianp
- * introduced VB
- *
- * Revision 1.8 1995/03/07 14:20:59 brianp
- * updated for new XSetForeground/GC scheme
- *
- * Revision 1.7 1995/03/04 19:29:44 brianp
- * 1.1 beta revision
- *
- * Revision 1.6 1995/03/02 19:18:54 brianp
- * new RasterMask logic
- * fixed Vcolor/Vbcolor bug in textured_polygon()
- *
- * Revision 1.5 1995/02/27 22:49:01 brianp
- * modified for PB
- *
- * Revision 1.4 1995/02/27 15:08:17 brianp
- * added Vcolor/Vindex scheme
- *
- * Revision 1.3 1995/02/26 22:58:57 brianp
- * made COMPUTE_PLANE_Z a function w/ FP overflow checking
- *
- * Revision 1.2 1995/02/25 22:07:43 brianp
- * more debugging code
- *
- * Revision 1.1 1995/02/24 14:26:49 brianp
- * Initial revision
- *
- */
-
-
- #include <string.h>
- #include "context.h"
- #include "dd.h"
- #include "feedback.h"
- #include "gamma.h"
- #include "interp.h"
- #include "lines.h"
- #include "list.h"
- #include "macros.h"
- #include "points.h"
- #include "span.h"
- #include "vb.h"
-
- /*#include "triangle.h"*/
-
-
- void glCullFace( GLenum mode )
- {
- if (CC.CompileFlag) {
- gl_save_cullface( mode );
- }
- if (CC.ExecuteFlag) {
- if (mode!=GL_FRONT && mode!=GL_BACK) {
- gl_error( GL_INVALID_ENUM, "glCullFace" );
- return;
- }
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glCullFace" );
- return;
- }
- CC.Polygon.CullFaceMode = mode;
- CC.NewState = GL_TRUE;
- }
- }
-
-
-
- void glFrontFace( GLenum mode )
- {
- if (CC.CompileFlag) {
- gl_save_frontface( mode );
- }
- if (CC.ExecuteFlag) {
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glFrontFace" );
- return;
- }
- if (mode!=GL_CW && mode!=GL_CCW) {
- gl_error( GL_INVALID_ENUM, "glFrontFace" );
- return;
- }
- CC.Polygon.FrontFace = mode;
- }
- }
-
-
-
- void glPolygonMode( GLenum face, GLenum mode )
- {
- if (CC.CompileFlag) {
- gl_save_polygonmode( face, mode );
- }
- if (CC.ExecuteFlag) {
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glPolygonMode" );
- return;
- }
- if (face!=GL_FRONT && face!=GL_BACK && face!=GL_FRONT_AND_BACK) {
- gl_error( GL_INVALID_ENUM, "glPolygonMode(face)" );
- return;
- }
- else if (mode!=GL_POINT && mode!=GL_LINE && mode!=GL_FILL) {
- gl_error( GL_INVALID_ENUM, "glPolygonMode(mode)" );
- return;
- }
-
- if (face==GL_FRONT || face==GL_FRONT_AND_BACK) {
- CC.Polygon.FrontMode = mode;
- }
- if (face==GL_BACK || face==GL_FRONT_AND_BACK) {
- CC.Polygon.BackMode = mode;
- }
-
- /* Compute a handy "shortcut" value: */
- if (CC.Polygon.FrontMode!=GL_FILL || CC.Polygon.BackMode!=GL_FILL) {
- CC.Polygon.Unfilled = GL_TRUE;
- }
- else {
- CC.Polygon.Unfilled = GL_FALSE;
- }
-
- CC.NewState = GL_TRUE;
- }
- }
-
-
-
- void glPolygonStipple( const GLubyte *mask )
- {
- if (CC.CompileFlag) {
- /*gl_save_polygon_stipple( mask );*/
- }
- if (CC.ExecuteFlag) {
- /* TODO: bit twiddling, unpacking */
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glPolygonStipple" );
- return;
- }
- MEMCPY( CC.PolygonStipple, mask, 32*sizeof(GLuint) );
- }
- }
-
-
-
- void glGetPolygonStipple( GLubyte *mask )
- {
- /* TODO */
- }
-
-
-
- void glPolygonOffsetEXT( GLfloat factor, GLfloat bias )
- {
- if (CC.CompileFlag) {
- gl_save_polygonoffset( factor, bias );
- }
- if (CC.ExecuteFlag) {
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glPolygonOffsetEXT" );
- return;
- }
- CC.Polygon.OffsetFactor = factor;
- CC.Polygon.OffsetBias = bias;
- }
- }
-
-
-
- /**********************************************************************/
- /***** Rasterization *****/
- /**********************************************************************/
-
-
- /*
- * Summary of polygon drawing functions:
- * feedback_polygon - when rendering mode is GL_FEEDBACK
- * select_polygon - when rendering mode is GL_SELECT
- * flat_ci_polygon - flat-shaded, any raster ops, RGBA polygon
- * smooth_ci_polygon - smooth-shaded, any raster ops, CI polygon
- * flat_rgba_polygon - flat-shaded, any raster ops, RGBA polygon
- * smooth_rgba_polygon - smooth-shaded, any raster ops, RGBA polygon
- * textured_polygon - smooth-shaded, textured RGBA polygon
- */
-
-
- /*
- * All polygon drawing functions have the same arguments:
- * n - number of vertices
- * vlist - array of indexes into the vertex list
- * pv - provoking vertex: which vertex color to use for flat shading.
- */
-
-
-
- /*
- * Evaluate the current polygon's plane equation at (x,y) to get Z.
- */
- GLint gl_compute_z( GLfloat x, GLfloat y )
- {
- GLfloat fz;
-
- fz = (CC.PlaneD - CC.PlaneA*x - CC.PlaneB*y) / CC.PlaneC;
-
- if (fz<0.0F) {
- return 0;
- }
- else if (fz>1.0F) {
- return MAX_DEPTH;
- }
-
- return (GLint) (fz * DEPTH_SCALE);
- }
-
-
- /* This macro can't be used for now. Sometimes the evaluation of the
- * plane equation at (x,y) results in a z which is too large or small
- * to store in an integer, causing a FP exception. We check for this
- * case in the above function.
-
- #define gl_compute_z( X, Y ) \
- ((CC.PlaneD - CC.PlaneA*(X) - CC.PlaneB*(Y)) / CC.PlaneC)
- */
-
-
-
-
- /*
- * Put polygon in feedback buffer.
- */
- static void feedback_polygon( GLuint n, GLuint vlist[], GLuint pv )
- {
- GLuint i;
-
- APPEND_TOKEN( (GLfloat) GL_POLYGON_TOKEN );
- APPEND_TOKEN( (GLfloat) n );
-
- for (i=0;i<n;i++) {
- GLfloat x, y, z, w;
- GLfloat tc[4];
- GLuint j = vlist[i];
-
- x = VB.Win[j][0];
- y = VB.Win[j][1];
- z = VB.Win[j][2];
- w = VB.Clip[j][3];
-
- tc[0] = VB.TexCoord[j][0];
- tc[1] = VB.TexCoord[j][1];
- tc[2] = 0.0F; /* TODO: R, Q components */
- tc[3] = 1.0F;
-
- gl_feedback_vertex( x, y, z, w, VB.Color[j], VB.Index[j], tc );
- }
- }
-
-
-
- /*
- * Put polygon in selection buffer.
- */
- static void select_polygon( GLuint n, GLuint vlist[], GLuint pv )
- {
- GLuint i;
-
- CC.HitFlag = GL_TRUE;
- for (i=0;i<n;i++) {
- GLuint j = vlist[i];
- GLfloat wz = VB.Win[j][2];
- if (wz < CC.HitMinZ) {
- CC.HitMinZ = wz;
- }
- if (wz > CC.HitMaxZ) {
- CC.HitMaxZ = wz;
- }
- }
- }
-
-
-
- /* Max number of pixels along a polygon's edge */
- #if MAX_WIDTH > MAX_HEIGHT
- # define EDGEMAX MAX_WIDTH
- #else
- # define EDGEMAX MAX_HEIGHT
- #endif
-
-
- /*
- * Left and right boundary values for polygon scan conversion
- */
- static GLfloat flx[MAX_HEIGHT], frx[MAX_HEIGHT];/* X bounds */
- static GLint li[MAX_HEIGHT], ri[MAX_HEIGHT]; /* Color Index */
- static GLint lr[MAX_HEIGHT], rr[MAX_HEIGHT]; /* Red */
- static GLint lg[MAX_HEIGHT], rg[MAX_HEIGHT]; /* Green */
- static GLint lb[MAX_HEIGHT], rb[MAX_HEIGHT]; /* Blue */
- static GLint la[MAX_HEIGHT], ra[MAX_HEIGHT]; /* Alpha */
- static GLfloat ls[MAX_HEIGHT], rs[MAX_HEIGHT]; /* S */
- static GLfloat lt[MAX_HEIGHT], rt[MAX_HEIGHT]; /* T */
-
-
-
- #ifdef LEAVEOUT
- /* THIS IS EXPERIMENTAL, NOT USED. */
- void gl_setup_edge( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
- GLfloat *x0, GLfloat *dx,
- GLint *ymin, GLint *ymax, GLint *dy )
- {
- GLfloat fy, slope;
-
- if (y1==y2) {
- /* skip horizontal edges */
- *ymin = *ymax = 0;
- return;
- }
-
- *dx = slope = (x2-x1) / (y2-y1);
-
- if (y1<y2) {
- *ymin = (int) (y1 + 0.5F);
- *ymax = (int) (y2 + 0.5F) - 0; /* ADD one? */
- fy = *ymin + 0.5F - y1;
- *x0 = x1 + fy * slope;
- *dy = 1;
- }
- else {
- *ymin = (int) (y2 + 0.5F);
- *ymax = (int) (y1 + 0.5F) - 0; /* ADD one? */
- fy = *ymax + 0.5F - y1;
- *x0 = x1 + fy * slope;
- *dx = -slope;
- *dy = 1;
- }
- }
- #endif
-
-
- /*
- * Compute the location of the pixels along the edge of a polygon.
- * Input: x1,y1, x2,y2 - endpoints of the polygon edge
- * Output: x, y - array of edge coords
- * Return: number of elements in x[], and y[]
- */
- #ifdef LEAVEOUT
- /* This version should be faster but unfortunately introduces a sampling bug */
- GLuint gl_polygon_edge( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
- GLfloat x[], GLint y[])
- {
- GLint ymin, ymax, iy;
- GLfloat slope, fx, fy;
- GLuint n;
-
- if (y1==y2) {
- /* skip horizontal edges */
- return 0;
- }
-
- slope = (x2-x1) / (y2-y1);
- n = 0;
- if (y1<y2) {
- ymin = (int) (y1 + 0.5F);
- ymax = (int) (y2 + 0.5F) - 1;
- fy = ymin + 0.5F - y1;
- fx = x1 + fy * slope;
- for (iy=ymin; iy<=ymax; iy++, fx+=slope, n++) {
- x[n] = fx;
- y[n] = iy;
- }
- }
- else {
- ymin = (int) (y2 + 0.5F);
- ymax = (int) (y1 + 0.5F) - 1;
- fy = ymax + 0.5F - y1;
- fx = x1 + fy * slope;
- for (iy=ymax; iy>=ymin; iy--, fx-=slope, n++) {
- x[n] = fx;
- y[n] = iy;
- }
- }
- return n;
- }
- #else
- /* this versions works but isn't the most efficient */
- GLuint gl_polygon_edge( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
- GLfloat x[], GLint y[])
- {
- GLint ymin, ymax, iy;
- GLfloat slope;
- GLuint i;
-
- if (y1==y2) {
- /* skip horizontal edges */
- return 0;
- }
-
- slope = (x2-x1) / (y2-y1);
- i = 0;
-
- if (y1<y2) {
- ymin = (int) (y1 + 0.5F);
- ymax = (int) (y2 + 0.5F) - 1;
- for (iy=ymin; iy<=ymax; iy++) {
- x[i] = x1 + ((iy+0.5F) - y1) * slope;
- y[i] = iy;
- i++;
- }
- }
- else {
- ymin = (int) (y2 + 0.5F);
- ymax = (int) (y1 + 0.5F) - 1;
- for (iy=ymax; iy>=ymin; iy--) {
- x[i] = x1 + ((iy+0.5F) - y1) * slope;
- y[i] = iy;
- i++;
- }
- }
- return i;
- }
-
- #endif
-
-
-
- static void flat_ci_polygon( GLuint n, GLuint vlist[], GLuint pv )
- {
- GLint i, j, y;
- GLint ymin, ymax;
- GLuint index;
-
- /* find min and max of window coordinate Y values */
- {
- GLfloat min = 1.0e10;
- GLfloat max = -1.0e10;
- if (n==3) {
- GLfloat winy;
- winy = VB.Win[vlist[0]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- winy = VB.Win[vlist[1]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- winy = VB.Win[vlist[2]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- }
- else {
- for (i=0;i<n;i++) {
- GLfloat winy = VB.Win[vlist[i]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- }
- }
- ymin = (GLint) min;
- ymin = CLAMP( ymin, 0, MAX_HEIGHT-1 ) ;
- ymax = (GLint) max;
- ymax = CLAMP( ymax, 0, MAX_HEIGHT-1 ) ;
- }
-
- /* init edge bounds */
- for (y=ymin;y<=ymax;y++) {
- flx[y] = (GLfloat) (MAX_WIDTH+1);
- frx[y] = -1.0;
- }
-
- /* process edges to compute span bounds */
- for (i=0;i<n;i++) {
- GLuint j0, j1, len;
- GLfloat ex[EDGEMAX];
- GLint ey[EDGEMAX];
-
- j0 = (i==0) ? vlist[n-1] : vlist[i-1];
- j1 = vlist[i];
-
- /* compute edge pixels */
- len = gl_polygon_edge( VB.Win[j0][0], VB.Win[j0][1],
- VB.Win[j1][0], VB.Win[j1][1],
- ex, ey );
-
- /* update bounds */
- for (j=0;j<len;j++) {
- GLfloat x = ex[j];
- GLint y = ey[j];
-
- if (y>=0 && y<MAX_HEIGHT) {
- if (x<flx[y]) {
- flx[y] = x;
- }
- if (x>frx[y]) {
- frx[y] = x;
- }
- }
- }
- }
-
- if (!VB.MonoColor) {
- /* set the color index */
- index = (GLuint) (GLint) VB.Index[pv];
- (*DD.index)( index );
- }
-
- /* process spans */
- /* TODO: don't always have to compute pixel depths! */
- for (y=ymin;y<=ymax;y++) {
- GLint xmin = (GLint) (flx[y] + 0.5);
- GLint xmax = (GLint) (frx[y] - 0.5);
- GLint len = xmax-xmin+1;
- if (len>0) {
- GLint z0, z1;
- GLint zspan[MAX_WIDTH];
-
- z0 = gl_compute_z( flx[y]+0.5F, (GLfloat) y + 0.5F );
- z1 = gl_compute_z( frx[y]-0.5F, (GLfloat) y + 0.5F );
- gl_interpolate_i( len, z0, z1, zspan );
-
- gl_write_monoindex_span( len, xmin, y, zspan, index, GL_POLYGON );
- }
- }
- }
-
-
-
- static void smooth_ci_polygon( GLuint n, GLuint vlist[], GLuint pv )
- {
- GLint i, j, y;
- GLint ymin, ymax;
-
- /* find min and max of window coordinate Y values */
- {
- GLfloat min = 1.0e10;
- GLfloat max = -1.0e10;
- if (n==3) {
- GLfloat winy;
- winy = VB.Win[vlist[0]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- winy = VB.Win[vlist[1]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- winy = VB.Win[vlist[2]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- }
- else {
- for (i=0;i<n;i++) {
- GLfloat winy = VB.Win[vlist[i]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- }
- }
- ymin = (GLint) min;
- ymin = CLAMP( ymin, 0, MAX_HEIGHT-1 ) ;
- ymax = (GLint) max;
- ymax = CLAMP( ymax, 0, MAX_HEIGHT-1 ) ;
- }
-
- /* init edge bounds */
- for (y=ymin;y<=ymax;y++) {
- flx[y] = (GLfloat) (MAX_WIDTH+1);
- frx[y] = -1.0;
- }
-
- /* process edges to compute bounds */
- for (i=0;i<n;i++) {
- GLuint j0, j1, len;
- GLfloat ex[EDGEMAX];
- GLint ey[EDGEMAX];
- GLuint ei[EDGEMAX];
-
- j0 = (i==0) ? vlist[n-1] : vlist[i-1];
- j1 = vlist[i];
-
- /* compute edge pixels */
- len = gl_polygon_edge( VB.Win[j0][0], VB.Win[j0][1],
- VB.Win[j1][0], VB.Win[j1][1],
- ex, ey );
-
- /* interpolate index along edge */
- gl_interpolate_i( len,
- (GLint) VB.Index[j0], (GLint) VB.Index[j1],
- (GLint *) ei );
-
- /* update bounds */
- for (j=0;j<len;j++) {
- GLfloat x = ex[j];
- GLint y = ey[j];
-
- if (y>=0 && y<MAX_DEPTH) {
- if (x < flx[y]) {
- flx[y] = x;
- li[y] = ei[j];
- }
- if (x > frx[y]) {
- frx[y] = x;
- ri[y] = ei[j];
- }
- }
- }
- }
-
- /* process spans */
- for (y=ymin;y<=ymax;y++) {
- GLint xmin = (GLint) (flx[y] + 0.5);
- GLint xmax = (GLint) (frx[y] - 0.5);
- GLint len = xmax-xmin+1;
- if (len>0) {
- GLint z0, z1;
- GLint zspan[MAX_WIDTH];
- GLuint index[MAX_WIDTH];
-
- /* interpolate z and index along span */
- z0 = gl_compute_z( flx[y]+0.5F, (GLfloat) y + 0.5F );
- z1 = gl_compute_z( frx[y]-0.5F, (GLfloat) y + 0.5F );
- gl_interpolate_i( len, z0, z1, zspan );
- gl_interpolate_i( len, li[y], ri[y], (GLint *) index );
-
- gl_write_index_span( len, xmin, y, zspan, index, GL_POLYGON );
- }
- }
- }
-
-
-
- static void flat_rgba_polygon( GLuint n, GLuint vlist[], GLuint pv )
- {
- GLint i, j, y;
- GLint ymin, ymax;
-
- /* find min and max of window coordinate Y values */
- {
- GLfloat min = 1.0e10;
- GLfloat max = -1.0e10;
- if (n==3) {
- GLfloat winy;
- winy = VB.Win[vlist[0]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- winy = VB.Win[vlist[1]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- winy = VB.Win[vlist[2]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- }
- else {
- for (i=0;i<n;i++) {
- GLfloat winy = VB.Win[vlist[i]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- }
- }
- ymin = (GLint) min;
- ymin = CLAMP( ymin, 0, MAX_HEIGHT-1 ) ;
- ymax = (GLint) max;
- ymax = CLAMP( ymax, 0, MAX_HEIGHT-1 ) ;
- }
-
- /* init edge bounds */
- for (y=ymin;y<=ymax;y++) {
- flx[y] = (GLfloat) (MAX_WIDTH+1);
- frx[y] = -1.0;
- }
-
- /* process edges to compute span bounds */
- for (i=0;i<n;i++) {
- GLuint j0, j1, len;
- GLfloat ex[EDGEMAX];
- GLint ey[EDGEMAX];
-
- j0 = (i==0) ? vlist[n-1] : vlist[i-1];
- j1 = vlist[i];
-
- /* compute edge pixels */
- len = gl_polygon_edge( VB.Win[j0][0], VB.Win[j0][1],
- VB.Win[j1][0], VB.Win[j1][1],
- ex, ey );
-
- /* update bounds */
- for (j=0;j<len;j++) {
- GLfloat x = ex[j];
- GLint y = ey[j];
-
- if (y>=0 && y<MAX_HEIGHT) {
- if (x<flx[y]) {
- flx[y] = x;
- }
- if (x>frx[y]) {
- frx[y] = x;
- }
- }
- }
- }
-
- if (!VB.MonoColor) {
- /* set the color */
- GLubyte r = (GLint) (VB.Color[pv][0] * CC.RedScale);
- GLubyte g = (GLint) (VB.Color[pv][1] * CC.GreenScale);
- GLubyte b = (GLint) (VB.Color[pv][2] * CC.BlueScale);
- GLubyte a = (GLint) (VB.Color[pv][3] * CC.AlphaScale);
- if (CC.RasterMask & GAMMA_BIT) {
- gl_apply_gamma( 1, &r, &g, &b );
- }
- (*DD.color)( r, g, b,a );
- }
-
- /* process spans */
- /* TODO: don't always have to compute pixel depths! */
- for (y=ymin;y<=ymax;y++) {
- GLint xmin = (GLint) (flx[y] + 0.5);
- GLint xmax = (GLint) (frx[y] - 0.5);
- GLint len = xmax-xmin+1;
- if (len>0) {
- GLint z0, z1;
- GLint zspan[MAX_WIDTH];
-
- z0 = gl_compute_z( flx[y]+0.5F, (GLfloat) y + 0.5F );
- z1 = gl_compute_z( frx[y]-0.5F, (GLfloat) y + 0.5F );
- gl_interpolate_i( len, z0, z1, zspan );
-
- gl_write_monocolor_span( len, xmin, y, zspan, VB.Color[pv],
- GL_POLYGON );
- }
- }
- }
-
-
-
-
- static void smooth_rgba_polygon( GLuint n, GLuint vlist[], GLuint pv )
- {
- GLint i, j, y;
- GLint ymin, ymax;
-
- /* find min and max of window coordinate Y values */
- {
- GLfloat min = 1.0e10;
- GLfloat max = -1.0e10;
- if (n==3) {
- GLfloat winy;
- winy = VB.Win[vlist[0]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- winy = VB.Win[vlist[1]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- winy = VB.Win[vlist[2]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- }
- else {
- for (i=0;i<n;i++) {
- GLfloat winy = VB.Win[vlist[i]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- }
- }
- ymin = (GLint) min;
- ymin = CLAMP( ymin, 0, MAX_HEIGHT-1 ) ;
- ymax = (GLint) max;
- ymax = CLAMP( ymax, 0, MAX_HEIGHT-1 ) ;
- }
-
- /* init edge bounds */
- for (y=ymin;y<=ymax;y++) {
- flx[y] = (GLfloat) (MAX_WIDTH+1);
- frx[y] = -1.0;
- }
-
- /* process edges to compute bounds */
- for (i=0;i<n;i++) {
- GLuint j0, j1, len;
- GLfloat ex[EDGEMAX];
- GLint ey[EDGEMAX];
- GLint r0, g0, b0, a0, r1, g1, b1, a1, dr, dg, db, da;
-
- j0 = (i==0) ? vlist[n-1] : vlist[i-1];
- j1 = vlist[i];
-
- /* compute edge pixels */
- len = gl_polygon_edge( VB.Win[j0][0], VB.Win[j0][1],
- VB.Win[j1][0], VB.Win[j1][1],
- ex, ey );
-
- /* setup for edge color interpolation */
- r0 = (GLint) (VB.Color[j0][0] * CC.RedScale) << 8;
- r1 = (GLint) (VB.Color[j1][0] * CC.RedScale) << 8;
- g0 = (GLint) (VB.Color[j0][1] * CC.GreenScale) << 8;
- g1 = (GLint) (VB.Color[j1][1] * CC.GreenScale) << 8;
- b0 = (GLint) (VB.Color[j0][2] * CC.BlueScale) << 8;
- b1 = (GLint) (VB.Color[j1][2] * CC.BlueScale) << 8;
- a0 = (GLint) (VB.Color[j0][3] * CC.AlphaScale) << 8;
- a1 = (GLint) (VB.Color[j1][3] * CC.AlphaScale) << 8;
- if (len>1) {
- GLint n = len-1;
- dr = (r1-r0) / n;
- dg = (g1-g0) / n;
- db = (b1-b0) / n;
- da = (a1-a0) / n;
- }
- else {
- dr = dg = db = da = 0;
- }
-
- /* update span bounds */
- for (j=0;j<len;j++) {
- GLfloat x = ex[j];
- GLint y = ey[j];
-
- if (y>=0 && y<MAX_HEIGHT) {
- if (x < flx[y]) {
- flx[y] = x;
- lr[y] = r0 >> 8;
- lg[y] = g0 >> 8;
- lb[y] = b0 >> 8;
- la[y] = a0 >> 8;
- }
- if (x > frx[y]) {
- frx[y] = x;
- rr[y] = r0 >> 8;
- rg[y] = g0 >> 8;
- rb[y] = b0 >> 8;
- ra[y] = a0 >> 8;
- }
- }
- r0 += dr; g0 += dg; b0 += db; a0 += da;
- }
- }
-
- /* process spans */
- for (y=ymin;y<=ymax;y++) {
- GLint xmin = (GLint) (flx[y] + 0.5);
- GLint xmax = (GLint) (frx[y] - 0.5);
- GLint len = xmax-xmin+1;
- if (len>0) {
- GLint z0, z1;
- GLint zspan[MAX_WIDTH];
- GLubyte red[MAX_WIDTH];
- GLubyte green[MAX_WIDTH];
- GLubyte blue[MAX_WIDTH];
- GLubyte alpha[MAX_WIDTH];
-
- /* interpolate z and colors */
- z0 = gl_compute_z( flx[y]+0.5F, (GLfloat) y + 0.5F );
- z1 = gl_compute_z( frx[y]-0.5F, (GLfloat) y + 0.5F );
- GL_INTERPOLATE_I( len, z0, z1, zspan );
- GL_INTERPOLATE_4UB( len,
- lr[y], rr[y], red,
- lg[y], rg[y], green,
- lb[y], rb[y], blue,
- la[y], ra[y], alpha );
-
- gl_write_color_span( len, xmin, y, zspan,
- red, green, blue, alpha, GL_POLYGON );
- }
- }
- }
-
-
-
- /*
- * This is a very special case function: RGBA mode, flat shaded,
- * depth buffered (GL_LESS) polygon.
- */
- static void fast_flat_rgba_z_polygon( GLuint n, GLuint vlist[], GLuint pv )
- {
- GLint i, j, y;
- GLint ymin, ymax;
-
- /* find min and max of window coordinate Y values */
- {
- GLfloat min = 1.0e10;
- GLfloat max = -1.0e10;
- if (n==3) {
- GLfloat winy;
- winy = VB.Win[vlist[0]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- winy = VB.Win[vlist[1]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- winy = VB.Win[vlist[2]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- }
- else {
- for (i=0;i<n;i++) {
- GLfloat winy = VB.Win[vlist[i]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- }
- }
- ymin = (GLint) min;
- ymin = CLAMP( ymin, 0, MAX_HEIGHT-1 ) ;
- ymax = (GLint) max;
- ymax = CLAMP( ymax, 0, MAX_HEIGHT-1 ) ;
- }
-
- /* init edge bounds */
- for (y=ymin;y<=ymax;y++) {
- flx[y] = (GLfloat) (MAX_WIDTH+1);
- frx[y] = -1.0;
- }
-
- if (!VB.MonoColor) {
- /* set the color */
- GLubyte r = (GLint) (VB.Color[pv][0] * CC.RedScale);
- GLubyte g = (GLint) (VB.Color[pv][1] * CC.GreenScale);
- GLubyte b = (GLint) (VB.Color[pv][2] * CC.BlueScale);
- GLubyte a = (GLint) (VB.Color[pv][3] * CC.AlphaScale);
- if (CC.RasterMask & GAMMA_BIT) {
- gl_apply_gamma( 1, &r, &g, &b );
- }
- (*DD.color)( r, g, b,a );
- }
-
- /* process edges to compute bounds */
- for (i=0;i<n;i++) {
- GLuint j0, j1, len;
- GLfloat ex[EDGEMAX];
- GLint ey[EDGEMAX];
-
- j0 = (i==0) ? vlist[n-1] : vlist[i-1];
- j1 = vlist[i];
-
- /* compute edge pixels */
- len = gl_polygon_edge( VB.Win[j0][0], VB.Win[j0][1],
- VB.Win[j1][0], VB.Win[j1][1],
- ex, ey );
-
- /* update span bounds */
- for (j=0;j<len;j++) {
- GLfloat x = ex[j];
- GLint y = ey[j];
- if (y>=0 && y<MAX_HEIGHT) {
- if (x < flx[y]) {
- flx[y] = x;
- }
- if (x > frx[y]) {
- frx[y] = x;
- }
- }
- }
- }
-
- /* process spans */
- for (y=ymin;y<=ymax;y++) {
- GLint xmin = (GLint) (flx[y] + 0.5);
- GLint xmax = (GLint) (frx[y] - 0.5);
- GLint len = xmax-xmin+1;
- if (len>0) {
- GLint zspan[MAX_WIDTH];
- GLubyte mask[MAX_WIDTH];
- GLint z0, z1, *zptr;
- GLuint passed = 0;
-
- /* interpolate z */
- z0 = gl_compute_z( flx[y]+0.5F, (GLfloat) y + 0.5F );
- z1 = gl_compute_z( frx[y]-0.5F, (GLfloat) y + 0.5F );
- GL_INTERPOLATE_I( len, z0, z1, zspan );
-
- /* do depth test */
- zptr = CC.DepthBuffer + y * CC.BufferWidth + xmin;
- for (i=0;i<len;i++) {
- if (zspan[i]<zptr[i]) {
- zptr[i] = zspan[i];
- mask[i] = 1;
- passed++;
- }
- else {
- mask[i] = 0;
- }
- }
- /* write pixels */
- if (passed>0) {
- (*DD.write_monocolor_span)( len, xmin, y, mask );
- }
- }
- }
- }
-
-
-
- /*
- * This is a very special case function: RGBA mode, smooth shaded,
- * depth buffered (GL_LESS) polygon.
- */
- static void fast_smooth_rgba_z_polygon( GLuint n, GLuint vlist[], GLuint pv )
- {
- GLint i, j, y;
- GLint ymin, ymax;
-
- /* find min and max of window coordinate Y values */
- {
- GLfloat min = 1.0e10;
- GLfloat max = -1.0e10;
- if (n==3) {
- GLfloat winy;
- winy = VB.Win[vlist[0]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- winy = VB.Win[vlist[1]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- winy = VB.Win[vlist[2]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- }
- else {
- for (i=0;i<n;i++) {
- GLfloat winy = VB.Win[vlist[i]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- }
- }
- ymin = (GLint) min;
- ymin = CLAMP( ymin, 0, MAX_HEIGHT-1 ) ;
- ymax = (GLint) max;
- ymax = CLAMP( ymax, 0, MAX_HEIGHT-1 ) ;
- }
-
- /* init edge bounds */
- for (y=ymin;y<=ymax;y++) {
- flx[y] = (GLfloat) (MAX_WIDTH+1);
- frx[y] = -1.0;
- }
-
- /* process edges to compute bounds */
- for (i=0;i<n;i++) {
- GLuint j0, j1, len;
- GLfloat ex[EDGEMAX];
- GLint ey[EDGEMAX];
- GLint r0, g0, b0, a0, r1, g1, b1, a1, dr, dg, db, da;
-
- j0 = (i==0) ? vlist[n-1] : vlist[i-1];
- j1 = vlist[i];
-
- /* compute edge pixels */
- len = gl_polygon_edge( VB.Win[j0][0], VB.Win[j0][1],
- VB.Win[j1][0], VB.Win[j1][1],
- ex, ey );
-
- /* interpolate colors along edge */
- r0 = (GLint) (VB.Color[j0][0] * CC.RedScale) << 8;
- r1 = (GLint) (VB.Color[j1][0] * CC.RedScale) << 8;
- g0 = (GLint) (VB.Color[j0][1] * CC.GreenScale) << 8;
- g1 = (GLint) (VB.Color[j1][1] * CC.GreenScale) << 8;
- b0 = (GLint) (VB.Color[j0][2] * CC.BlueScale) << 8;
- b1 = (GLint) (VB.Color[j1][2] * CC.BlueScale) << 8;
- a0 = (GLint) (VB.Color[j0][3] * CC.AlphaScale) << 8;
- a1 = (GLint) (VB.Color[j1][3] * CC.AlphaScale) << 8;
- if (len>1) {
- GLint n = len-1;
- dr = (r1-r0) / n;
- dg = (g1-g0) / n;
- db = (b1-b0) / n;
- da = (a1-a0) / n;
- }
- else {
- dr = dg = db = da = 0;
- }
-
- /* update span bounds */
- for (j=0;j<len;j++) {
- GLfloat x = ex[j];
- GLint y = ey[j];
- if (y>=0 && y<MAX_HEIGHT) {
- if (x < flx[y]) {
- flx[y] = x;
- lr[y] = r0 >> 8;
- lg[y] = g0 >> 8;
- lb[y] = b0 >> 8;
- la[y] = a0 >> 8;
- }
- if (x > frx[y]) {
- frx[y] = x;
- rr[y] = r0 >> 8;
- rg[y] = g0 >> 8;
- rb[y] = b0 >> 8;
- ra[y] = a0 >> 8;
- }
- }
- r0 += dr; g0 += dg; b0 += db; a0 += da;
- }
- }
-
- /* process spans */
- for (y=ymin;y<=ymax;y++) {
- GLint xmin = (GLint) (flx[y] + 0.5);
- GLint xmax = (GLint) (frx[y] - 0.5);
- GLint len = xmax-xmin+1;
- if (len>0) {
- GLint zspan[MAX_WIDTH];
- GLubyte red[MAX_WIDTH];
- GLubyte green[MAX_WIDTH];
- GLubyte blue[MAX_WIDTH];
- GLubyte alpha[MAX_WIDTH];
- GLubyte mask[MAX_WIDTH];
- GLint z0, z1, *zptr;
- GLint r, g, b, a, dr, dg, db, da;
- GLuint passed = 0;
-
- /* interpolate z */
- z0 = gl_compute_z( flx[y]+0.5F, (GLfloat) y + 0.5F );
- z1 = gl_compute_z( frx[y]-0.5F, (GLfloat) y + 0.5F );
- GL_INTERPOLATE_I( len, z0, z1, zspan );
-
- /* setup for color interpolation */
- r = lr[y] << 8;
- g = lg[y] << 8;
- b = lb[y] << 8;
- a = la[y] << 8;
- if (len>1) {
- dr = ((rr[y] << 8) - r) / (len-1);
- dg = ((rg[y] << 8) - g) / (len-1);
- db = ((rb[y] << 8) - b) / (len-1);
- da = ((ra[y] << 8) - a) / (len-1);
- }
- else {
- dr = dg = db = da = 0;
- }
-
- /* do depth test */
- zptr = CC.DepthBuffer + y * CC.BufferWidth + xmin;
- for (i=0;i<len;i++) {
- if (zspan[i]<zptr[i]) {
- zptr[i] = zspan[i];
- mask[i] = 1;
- red[i] = r >> 8;
- green[i] = g >> 8;
- blue[i] = b >> 8;
- alpha[i] = a >> 8;
- passed++;
- }
- else {
- mask[i] = 0;
- }
- r += dr; g += dg; b += db; a += da;
- }
- /* write pixels */
- if (passed>0) {
- (*DD.write_color_span)( len, xmin, y,
- red, green, blue, alpha, mask );
- }
- }
- }
- }
-
-
-
- static void textured_polygon( GLuint n, GLuint vlist[], GLuint pv )
- {
- GLint i, j, y;
- GLint ymin, ymax;
- GLfloat leyez[MAX_HEIGHT], reyez[MAX_HEIGHT];
-
- /* find min and max of window coordinate Y values */
- {
- GLfloat min = 1.0e10;
- GLfloat max = -1.0e10;
- if (n==3) {
- GLfloat winy;
- winy = VB.Win[vlist[0]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- winy = VB.Win[vlist[1]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- winy = VB.Win[vlist[2]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- }
- else {
- for (i=0;i<n;i++) {
- GLfloat winy = VB.Win[vlist[i]][1];
- if (winy > max) max = winy;
- if (winy < min) min = winy;
- }
- }
- ymin = (GLint) min;
- ymin = CLAMP( ymin, 0, MAX_HEIGHT-1 ) ;
- ymax = (GLint) max;
- ymax = CLAMP( ymax, 0, MAX_HEIGHT-1 ) ;
- }
-
- /* init edge bounds */
- for (y=ymin;y<=ymax;y++) {
- flx[y] = (GLfloat) (MAX_WIDTH+1);
- frx[y] = -1.0;
- }
-
- /* process edges to compute bounds */
- for (i=0;i<n;i++) {
- GLuint j0, j1, len;
- DEFARRAY( GLfloat, ex, EDGEMAX ); /* x in win coords */
- DEFARRAY( GLint, ey, EDGEMAX ); /* y in win coords */
- DEFARRAY( GLfloat, ez, EDGEMAX ); /* z in eye coords */
- DEFARRAY( GLfloat, es, EDGEMAX ); /* texture s,t */
- DEFARRAY( GLfloat, et, EDGEMAX );
- GLint r0, g0, b0, a0, r1, g1, b1, a1, dr, dg, db, da;
-
-
- j0 = (i==0) ? vlist[n-1] : vlist[i-1];
- j1 = vlist[i];
-
- /* compute edge pixels */
- len = gl_polygon_edge( VB.Win[j0][0], VB.Win[j0][1],
- VB.Win[j1][0], VB.Win[j1][1],
- ex, ey );
-
- /* setup for edge color interpolation */
- r0 = (GLint) (VB.Color[j0][0] * CC.RedScale) << 8;
- r1 = (GLint) (VB.Color[j1][0] * CC.RedScale) << 8;
- g0 = (GLint) (VB.Color[j0][1] * CC.GreenScale) << 8;
- g1 = (GLint) (VB.Color[j1][1] * CC.GreenScale) << 8;
- b0 = (GLint) (VB.Color[j0][2] * CC.BlueScale) << 8;
- b1 = (GLint) (VB.Color[j1][2] * CC.BlueScale) << 8;
- a0 = (GLint) (VB.Color[j0][3] * CC.AlphaScale) << 8;
- a1 = (GLint) (VB.Color[j1][3] * CC.AlphaScale) << 8;
- if (len>1) {
- GLint n = len-1;
- dr = (r1-r0) / n;
- dg = (g1-g0) / n;
- db = (b1-b0) / n;
- da = (a1-a0) / n;
- }
- else {
- dr = dg = db = da = 0;
- }
-
- gl_interp_texcoords( len, VB.Eye[j0][2], VB.Eye[j1][2],
- VB.Win[j0][2] * MAX_DEPTH, VB.Win[j1][2] * MAX_DEPTH,
- VB.TexCoord[j0][0], VB.TexCoord[j1][0],
- VB.TexCoord[j0][1], VB.TexCoord[j1][1],
- es, et, ez );
-
- /* update span bounds */
- for (j=0;j<len;j++) {
- register GLfloat x = ex[j];
- register GLint y = ey[j];
-
- if (y>=0 && y<MAX_HEIGHT) {
- /* update left and right span bounds */
- if (x < flx[y]) {
- flx[y] = x;
- lr[y] = r0 >> 8;
- lg[y] = g0 >> 8;
- lb[y] = b0 >> 8;
- la[y] = a0 >> 8;
- ls[y] = es[j];
- lt[y] = et[j];
- leyez[y] = ez[j];
- }
- if (x > frx[y]) {
- frx[y] = x;
- rr[y] = r0 >> 8;
- rg[y] = g0 >> 8;
- rb[y] = b0 >> 8;
- ra[y] = a0 >> 8;
- rs[y] = es[j];
- rt[y] = et[j];
- reyez[y] = ez[j];
- }
- }
- r0 += dr; g0 += dg; b0 += db; a0 += da;
- }
- UNDEFARRAY( ex );
- UNDEFARRAY( ey );
- UNDEFARRAY( ez );
- UNDEFARRAY( es );
- UNDEFARRAY( et );
- }
-
- /* process spans */
- for (y=ymin;y<=ymax;y++) {
- GLint xmin = (GLint) (flx[y] + 0.5);
- GLint xmax = (GLint) (frx[y] - 0.5);
- GLint len = xmax-xmin+1;
- if (len>0) {
- GLint z0, z1;
- GLint zspan[MAX_WIDTH];
- GLubyte red[MAX_WIDTH];
- GLubyte green[MAX_WIDTH];
- GLubyte blue[MAX_WIDTH];
- GLubyte alpha[MAX_WIDTH];
- GLfloat s[MAX_WIDTH], t[MAX_WIDTH];
-
- /* interpolate z, colors and tex coords */
- z0 = gl_compute_z( flx[y]+0.5F, (GLfloat) y + 0.5F );
- z1 = gl_compute_z( frx[y]-0.5F, (GLfloat) y + 0.5F );
- GL_INTERPOLATE_I( len, z0, z1, zspan );
- GL_INTERPOLATE_4UB( len,
- lr[y], rr[y], red,
- lg[y], rg[y], green,
- lb[y], rb[y], blue,
- la[y], ra[y], alpha );
-
- gl_interp_texcoords( len, leyez[y], reyez[y],
- (GLfloat) z0, (GLfloat) z1,
- ls[y], rs[y], lt[y], rt[y],
- s, t, NULL );
-
- gl_write_texture_span( len, xmin, y, zspan, s, t,
- red, green, blue, alpha, GL_POLYGON );
- }
- }
- }
-
-
-
-
- /*
- * Render a polygon whose front or back rendering modes are point or line.
- */
- static void unfilled_polygon( GLuint n, GLuint vlist[], GLuint pv )
- {
- GLuint i, j, j0, j1;
- GLuint facing = (VB.Color==VB.Bcolor); /* 0=front, 1=back */
-
- CC.StippleCounter = 0; /* in case we're drawing polygon outline */
-
- if (facing==0) {
- /* Front */
- if (CC.Polygon.FrontMode==GL_POINT) {
- for (i=0;i<n;i++) {
- j = vlist[i];
- if (VB.Edgeflag[j]) {
- (*CC.PointsFunc)( j, j );
- }
- }
- }
- else if (CC.Polygon.FrontMode==GL_LINE) {
- for (i=0;i<n;i++) {
- j0 = (i==0) ? vlist[n-1] : vlist[i-1];
- j1 = vlist[i];
- if (VB.Edgeflag[j0]) {
- (*CC.LineFunc)( j0, j1, pv );
- }
- }
- }
- else {
- (*CC.AuxPolygonFunc)( n, vlist, pv );
- }
- }
- else {
- /* Back */
- if (CC.Polygon.BackMode==GL_POINT) {
- for (i=0;i<n;i++) {
- j = vlist[i];
- if (VB.Edgeflag[j]) {
- (*CC.PointsFunc)( j, j );
- }
- }
- }
- else if (CC.Polygon.BackMode==GL_LINE) {
- for (i=0;i<n;i++) {
- j0 = (i==0) ? vlist[n-1] : vlist[i-1];
- j1 = vlist[i];
- if (VB.Edgeflag[j0]) {
- (*CC.LineFunc)( j0, j1, pv );
- }
- }
- }
- else {
- (*CC.AuxPolygonFunc)( n, vlist, pv );
- }
- }
- }
-
-
-
- /*
- * Determine which polygon rendering function to use given the current
- * rendering context.
- */
- void gl_set_polygon_function( void )
- {
- if (CC.RenderMode==GL_RENDER) {
- CC.PolygonFunc = (*DD.get_polygon_func)();
- if (CC.PolygonFunc) {
- /* Device Driver will draw the polygon */
- }
- else if (CC.Texture.Enabled) {
- /* textured */
- CC.PolygonFunc = textured_polygon;
- }
- else if (CC.RGBAflag
- && CC.Color.ColorMask==0xf
- && CC.RasterMask==DEPTH_BIT
- && CC.Depth.Func==GL_LESS
- && CC.Depth.Mask==GL_TRUE
- && CC.Polygon.StippleFlag==GL_FALSE
- && CC.Texture.Enabled==0
- && CC.ClipSpans==GL_FALSE) {
- /* Common cases */
- if (CC.Light.ShadeModel==GL_SMOOTH) {
- CC.PolygonFunc = fast_smooth_rgba_z_polygon;
- }
- else {
- CC.PolygonFunc = fast_flat_rgba_z_polygon;
- }
- }
- else {
- if (CC.Light.ShadeModel==GL_SMOOTH) {
- /* smooth shaded, no texturing, stippled or some raster ops */
- CC.PolygonFunc = CC.RGBAflag ? smooth_rgba_polygon : smooth_ci_polygon;
- }
- else {
- /* flat shaded, no texturing, stippled or some raster ops */
- CC.PolygonFunc = CC.RGBAflag ? flat_rgba_polygon : flat_ci_polygon;
- }
- }
-
- /* PolygonMode */
- if (CC.Polygon.Unfilled) {
- /* front or back are to be rendered as points or lines */
- if (!CC.PointsFunc) {
- gl_set_point_function();
- }
- if (!CC.LineFunc) {
- gl_set_line_function();
- }
- CC.AuxPolygonFunc = CC.PolygonFunc;
- CC.PolygonFunc = unfilled_polygon;
- }
- }
- else if (CC.RenderMode==GL_FEEDBACK) {
- CC.PolygonFunc = feedback_polygon;
- }
- else {
- /* GL_SELECT mode */
- CC.PolygonFunc = select_polygon;
- }
- }
-
-
-